package com.tanhua.sso.service;

import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.LineCaptcha;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.tanhua.common.mapper.AdminMapper;
import com.tanhua.common.pojo.Admin;
import com.tanhua.sso.vo.BackgroundUserVo;
import io.jsonwebtoken.JwsHeader;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Service
@Slf4j
public class BackstageLoginService {

    @Autowired
    private RedisTemplate<String,String> redisTemplate;

    @Autowired
    private AdminMapper adminMapper;


    //加密盐
    private final String secret = "itcast";


    public LineCaptcha VerificationCode(String uuid){
        //HuTool定义图形验证码的长和宽,验证码的位数，干扰线的条数
        LineCaptcha lineCaptcha = CaptchaUtil.createLineCaptcha(116, 36,4,10);
        String key = "Code_" + uuid;
        String code = lineCaptcha.getCode();
        redisTemplate.opsForValue().set(key,code);
//        redisTemplate.opsForValue().set(key,"1234");
        return lineCaptcha;
    }

    public String userLogin(JSONObject jsonParam){//String username, String password, String verificationCode, String uuid) {
        String username = jsonParam.get("username").toString();
        String password = jsonParam.get("password").toString();
        String verificationCode = jsonParam.get("verificationCode").toString();
        String uuid = jsonParam.get("uuid").toString();
        String pw = null;
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            // 计算md5函数
            md.update(password.getBytes());

            pw = new BigInteger(1, md.digest()).toString(16);
        } catch (NoSuchAlgorithmException e) {
            log.error("md5加密出错");
        }

        QueryWrapper<Admin> query = new QueryWrapper<>();
        query.eq("username",username);
        query.eq("password",pw);

        Admin admin = adminMapper.selectOne(query);
        //查询用户是否为空
        if (ObjectUtil.isEmpty(admin)){
            return null;
        }
        //验证验证码是否相等
        String key = "Code_" + uuid;
        String s = redisTemplate.opsForValue().get(key);
        redisTemplate.delete(key);
        if (!StringUtils.equals(verificationCode,s)){
            return null;
        }

        Long id = admin.getId();

        //生成token
        Map<String, Object> header = new HashMap<String, Object>();
        header.put(JwsHeader.TYPE, JwsHeader.JWT_TYPE);
        header.put(JwsHeader.ALGORITHM, "HS256");

        Map<String, Object> claims = new HashMap<String, Object>();
        claims.put("id",id);


        // 生成token
        String token = Jwts.builder()
                .setClaims(claims) //payload，存放数据的位置，不能放置敏感数据，如：密码等
                .signWith(SignatureAlgorithm.HS256, secret) //设置加密方法和加密盐
                .setExpiration(new Date(System.currentTimeMillis() + 3000)) //设置过期时间，3秒后过期
                .setExpiration(new DateTime().plusHours(12).toDate()) //设置过期时间，12小时后过期
                .compact();

        String tokenKey = "token" + id;
        redisTemplate.opsForValue().set(tokenKey,token);

        return token;
    }

    //登录展示用户信息
    public BackgroundUserVo getBackgroundInfo(String token) {

        //前台传过来的token前面有个单词，分割
            String[] s = token.split(" ");
            token = s[1];

        BackgroundUserVo backgroundUserVo = getBackgroundUserVo(token);
        return backgroundUserVo;
    }

    //退出登录
    public void backgroundLogout(String token) {
        String[] s = token.split(" ");
        token = s[1];
        BackgroundUserVo backgroundInfo = getBackgroundUserVo(token);
        String uid = backgroundInfo.getUid();
        String tokenKey = "token" + uid;
        redisTemplate.delete(tokenKey);

    }

    //根据token获取BackgroundUserVo对象
    public BackgroundUserVo getBackgroundUserVo(String token){
        Map<String, Object> body = Jwts.parser()
                .setSigningKey(secret)
                .parseClaimsJws(token)
                .getBody();
        String id = body.get("id").toString();

        if (!ObjectUtil.isNotEmpty(id)){
            return null;
        }

        QueryWrapper<Admin> query = new QueryWrapper();
        query.eq("id",id);
        Admin admin = adminMapper.selectOne(query);
        String username = admin.getUsername();
        String avatar = admin.getAvatar();

        BackgroundUserVo backgroundUserVo = new BackgroundUserVo(id,username,avatar);

        return backgroundUserVo;
    }
}
